package ua.com.myjava.francais;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.mongo.MongoClient;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.CookieHandler;
import io.vertx.ext.web.handler.SessionHandler;
import io.vertx.ext.web.handler.StaticHandler;
import io.vertx.ext.web.handler.sockjs.BridgeOptions;
import io.vertx.ext.web.handler.sockjs.PermittedOptions;
import io.vertx.ext.web.handler.sockjs.SockJSHandler;
import io.vertx.ext.web.sstore.LocalSessionStore;

import java.nio.file.Files;
import java.nio.file.Paths;


public class Server extends AbstractVerticle {

    // Convenience method so you can run it in your IDE
    public static void main(String[] args) throws Exception {
        Vertx vertx = Vertx.vertx();
        DeploymentOptions options = new DeploymentOptions()
                .setConfig(new JsonObject(new String(Files.readAllBytes(Paths.get(Thread.currentThread().getContextClassLoader().getResource("francais-conf.json").toURI())))));
        vertx.deployVerticle(new Server(), options);
    }

    @Override
    public void start() throws Exception {
        // Create a mongo client using all defaults (connect to localhost and default port) using the database name "demo".
        ImageService imageService = new ImageService(MongoClient.createShared(vertx, new JsonObject()
                .put("host", config().getString("mongo.host"))
                .put("port", config().getInteger("mongo.port"))
                .put("user", config().getString("mongo.user"))
                .put("pass", config().getString("mongo.pass"))
                .put("db_name", config().getString("mongo.db"))));

        // the app works 100% realtime
        vertx.eventBus().consumer("vtoons.listImages", imageService::listImages);
        vertx.eventBus().consumer("vtoons.addImage", imageService::addImage);

        Router router = Router.router(vertx);

        // We need cookies and sessions
        router.route().handler(CookieHandler.create());
        router.route().handler(BodyHandler.create());
        router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));
        router.route("/login-fb").handler(FbLoginHandler.create(vertx));
        router.route("/callback-fb").handler(FbLoginHandler.create(vertx));
        // Allow outbound traffic to the vtoons addresses
        BridgeOptions options = new BridgeOptions()
                .addInboundPermitted(new PermittedOptions()
                        .setAddress("vtoons.listImages"))
                .addInboundPermitted(new PermittedOptions()
                        .setAddress("vtoons.addImage"))
                        // all outbound messages are permitted
                .addOutboundPermitted(new PermittedOptions());

        // Implement logout
        router.route("/logout").handler(context -> {
            context.addCookie(context.getCookie("login_success").setMaxAge(0));
            context.addCookie(context.getCookie("expires_at").setMaxAge(0));
            context.clearUser();
            // Redirect back to the index page
            context.response().putHeader("location", "/").setStatusCode(302).end();
        });

        router.route("/eventbus/*").handler(SockJSHandler.create(vertx).bridge(options));
        // Serve the static resources
        router.route().handler(StaticHandler.create(config().getString("webapp")));
        vertx.createHttpServer().requestHandler(router::accept).listen(config().getInteger("http.port"));
    }

}
